import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  /**
   * new Vue({})时
   * 即调用_init函数
   * 该函数被定义时间
   * initMixin(Vue)
   */
  this._init(options)
}

/**
 * 注册_init函数:
 * this._init(options)
 * 在new Vue({})时调用，初始化vm实例
 * 处理实例对象数据
 * src\core\instance\init.js
 */
initMixin(Vue)
/**
 * 使用Object.defineProperty
 * 特殊处理
 * 在Vue.prototype上挂载以下函数
 * $data、$props
 * $set、$watch、$delete
 */
stateMixin(Vue)
/**
 * 混入与事件相关的函数
 * $on、$off、$once、$emit
 * 采用发布-订阅的设计模式
 */
eventsMixin(Vue)
/**
 * 混入与生命周期相关的函数
 * _update、$forceUpdate、$destroy
 * _update函数中调用vm.__patch__函数
 * 即进行diff算法，比较新旧vdom节点，
 * 并渲染成真实dom元素
 * 在渲染视图时调用，包括首次渲染、数据更新时
 */
lifecycleMixin(Vue)
/**
 * 通过installRenderHelpers(Vue.prototype)函数:
 * 在Vue.prototype上定义许多编译时使用的辅助函数
 * 混入与渲染相关的函数
 * $nextTick、与Vue.nextTick对应
 * _render:
 * 函数体部分代码:
 * const { render, _parentVnode } = vm.$options
 * vnode = render.call(vm._renderProxy, vm.$createElement)
 * 返回值:vnode
 * vm.$createElement，即传入的h函数
 * 在调用this._init(options)时给vm实例上添加的$createElement函数
 * 即./init.js中调用initRender(vm)时添加
 */
renderMixin(Vue)

export default Vue
